var showInfo, showHideResults, toggleMap, featuresToCSV;
/**
 * Class that contains most of the feature and user interface controls.
 * 
 * @param {object} map The OpenLayers map object. 
 * @param {object} wfs The OpenLayers vector layer.
 * @returns A div element filled with wfs data that is shown on click.
 */
 
function FeatureInformation(map, wfs) {
    "use strict";
    var info_open = null,
        click = new OpenLayers.Control.SelectFeature(wfs, {
            toggle: true,
            multiple: true,
            clickout: false,
            onSelect: showFeature,
            onUnselect: hideFeature
        }),
        locationtypes,
        locationtypegroups,
        municipalities,
        counties;
    
    map.addControl(click);
    click.activate();

    locationtypes = new setJSONdata("location_types");
    locationtypegroups = new setJSONdata("location_type_groups");
    municipalities = new setJSONdata("municipalities");
    counties = new setJSONdata("counties");

    /**
     * Converts feature data to string.
     *
     * @param {object} pdata The data contained by a feature.
     * @returns A string object that contains the relevant data.
     */
    function toString (feature) {
        var resultstr = '',
            pdata = feature.data,
            bounds = feature.bounds,
            language = $("#languageSelect").val(),
            locationtype = locationtypes[pdata.paikkatyyppiKoodi.replace(/^[0]+/g, "")],
            locationtypegroup = locationtypegroups[pdata.paikkatyyppiryhmaKoodi.replace(/^[0]+/g, "")],
            municipality = municipalities[pdata.kuntaKoodi.replace(/^[0]+/g, "")],
            county = counties[pdata.maakuntaKoodi.replace(/^[0]+/g, "")],
            foreignnames = [],
            key;
        resultstr += 'PaikkaID=' + pdata.paikkaID + '???';
        resultstr += 'Paikkatyyppi=' + locationtype[language] + '???';
        resultstr += 'Paikkatyyppiryhmä=' + locationtypegroup[language] + '???';
        resultstr += 'Kunta=' + municipality[language] + '???';
        resultstr += 'Maakunta=' + county[language] + '???';
        resultstr += 'Koordinaatit=' + bounds.bottom + 'N, ' + bounds.left + 'E';
        if (Object.keys(feature.names).length > 1) {
            resultstr += '???Muut nimet=';
            for (key in feature.names) {
                if (key !== language) {
                    resultstr += feature.names[key].kirjoitusasu + "(" + key + "), ";
                }
            }
            //Remove whitespace and the extra comma from the end of the string
            resultstr = resultstr.replace(/^\s+|\s+$/g, '');
            resultstr = resultstr.substring(0, resultstr.length-1);
        }
        return resultstr;
    }

    /**
     * Function returns key value pairs.
     *
     * @param {string} data The data of a feature as returned by the toString function
     *  of this class.
     * @returns The value pairs of the data given in a html list (excluding the ul tags!).
     */
    function getValuePairs(data) {
        var values = data.split("???"),
            values_code = "",
            pair,
            lonlat,
            i;

        // Get information from feature data
        for (i in values) {
            if (values[i] !== "__proto__") {
                pair = values[i].split("=");
                values_code += "<li>" + pair[0] + ": " + pair[1] + "</li>";
            }
        }
        return values_code;
    }

    /**
     * Shows information of a feature in results div when it is selected.
     *
     * @param {object} feature A feature returned from the land survey WFS interface.
     */
    function showFeature(feature) {
        var id = feature.fid,
            data = toString(feature),
            values_code,
            lonlat;

        values_code += '<ul>';
        values_code = getValuePairs(data);
        values_code += '</ul>';

        // Show information on feature
        if ($("#cat_" + id + "_info_open").length === 0) {
            $("#cat_" + id).after("<div class='resultDetails' id='cat_" + id + "_info_open'>" +
                values_code + "<button class=\"resultbutton\" id='cat_" + id + "_button'>sulje</button></div>");
            $("#sidepanel").scrollTop(0);
            $("#sidepanel").stop().animate({
                scrollTop: $("#cat_" + id).offset().top - 100
            }, 0);
        } else {
            click.unselect(feature);
        }
        // Hide information if button is clicked
        $("#cat_" + id + "_button").click(function () {
            click.unselect(feature);
        });
        feature.info_open = true;

        // Change coordinates of radial search
        lonlat = feature.bounds.getCenterLonLat();
        new WFS().updatePointField(lonlat.lon, lonlat.lat);
    }

    /**
     * Hides information of given feature when it is unselected.
     *
     * @param {object} feature A feature returned from the land survey WFS interface.
     */
    function hideFeature(feature) {
        feature.info_open = false;
        $("#cat_" + feature.fid + "_info_open").remove();
    }

    /**
     * Function to highlight feature on the map and show data of the feature in the result list.
     *
     * @param {string} id The id of a feature returned from the land survey WFS interface.
     */
    showInfo = function (id) {
        click.select(wfs.getFeatureBy('fid', id));
    };

    /**
     * Detects if the results are already visible in the result list.
     *
     * @param {string} type The type of the feature returned from the land survey WFS interface.
     * @param {string} id The id of a feature returned from the land survey WFS interface.
     */
    showHideResults = function (type, id) {
        if ($("#" + type + "_" + id).children().length !== 0) {
            $("#" + type + "_" + id).children().filter(":not(#" + type + "_" + id +
                "_header)").filter(":not(#visibility_" + type + "_" + id + ")").toggle();
        }
    };

    /**
     * Function to draw and remove features on the map by location type.
     *
     * @param {string} type The location type of a feature on the map.
     * @param {string} type_id The id of the location type.
     */
    toggleMap = function (type, type_id) {
        var id = type_id.toString(),
            features,
            municipalityCodes = [],
            i,
            j;

        if (type === "locationTypeGroup") {
            features = wfs.getFeaturesByAttribute('paikkatyyppiryhmaKoodi', id);
        } else if (type === "locationType") {
            features = wfs.getFeaturesByAttribute('paikkatyyppiKoodi', id);
        }
        if ($("#visibility_" + type + "_" + id).is(":checked")) {
            for (i in features) {
                features[i].renderIntent = 'default';
                wfs.drawFeature(features[i]);
                $("#list_" + features[i].fid).show();
            }
        } else {
            for (i in features) {
                if (features[i] !== "__proto__") {
                    features[i].renderIntent = 'delete';
                    wfs.drawFeature(features[i]);
                    $("#list_" + features[i].fid).hide();
                }
            }
        }
    };

    /**
     * Creates the div for the groups.
     *
     * @param {string} type The location type of a feature on the map.
     * @param {string} id The id of the location type of a feature.
     * @param {string} typestring The name of the location type.
     * @param {integer} headervalue The value of the header level.
     */
    function createGroupDiv(type, id, type_string, header_value) {
        return "<div id='" + type + "_" + id +
            "' class='groups'><input class='resultcheckbox' type='checkbox' checked style='float: left;' id='visibility_" + type + "_" +
            id + "' onclick=toggleMap('" + type + "','" + id + "') /><h" + header_value + " id='" + type + "_" +
            id + "_header' onclick=showHideResults('" + type + "','" + id + "') class='subgroupheader headerlevel" + header_value + "'>" +
            type_string + ":</h" + header_value + "></div>";
    }

    /**
     * Function to add a feature to the correct div element.
     *
     * @param {string} type_group The location type group of a feature on the map.
     * @param {object} feature A feature on the map.
     * @param {string} municipality_name The name of the municipality of a feature on the map.
     * @param {string} location_type The location type of a feature on the map.
     */
    function addFeatureIntoGroup(type_group, feature, municipality_name, location_type, language) {
     var data = feature.data,
         fid  = feature.fid,
         string_data = toString(feature),
         values_code,
         name;

     values_code = getValuePairs(string_data);

     if(feature.names[language] != null){
         name = feature.names[language].kirjoitusasu;
     } else {
         name = data.kirjoitusasu;
     }

     $("#" + type_group +"_" + data.paikkatyyppiKoodi).append("<div id='cat_" + fid +
         "' onclick='showInfo(\"" + fid + "\")' class='categoryList'>" +
         "<span>" + name + ",</span>" +
         " Kunta: <span>" + municipality_name + "</span>" +
         "</div>");

     $("#listView").append("<div id='list_" + fid + "' class='listList'><b>" + name +
         "</b><ul>" + values_code + "</ul></div>");    
    }

    /**
     * Function does not add locations to the list view or the map if they are unchecked in the category view.
     */
    function removeUnCheckedLocations() {
        var i,
            features = wfs.features;
        for (i in features) {
            if (($("#visibility_locationTypeGroup_" + features[i].data.paikkatyyppiryhmaKoodi)).is(":checked") === false ||
                    ($("#visibility_locationType_" + features[i].data.paikkatyyppiKoodi)).is(":checked") === false) {
                features[i].renderIntent = 'delete';
                wfs.drawFeature(features[i]);
                $("#list_" + features[i].fid).hide();
            }
        }
    }

    /**
     * Creates the category listing of a feature.
     *
     * @param {object} feature A feature on the map.
     * @param {string} language The language of the name of the feature to be retrieved.
     */
    function addFeatureListing(feature, language) {
        var data = feature.data,
            locationTypeGroup,
            municipality,
            locationType,
            appendableItem,
            text;

        if (data !== null) {
            locationTypeGroup = locationtypegroups[data.paikkatyyppiryhmaKoodi.replace(/^[0]+/g, "")];
            municipality = municipalities[data.kuntaKoodi.replace(/^[0]+/g, "")];
            locationType = locationtypes[data.paikkatyyppiKoodi.replace(/^[0]+/g, "")];

            if ($("#locationTypeGroup_" + data.paikkatyyppiryhmaKoodi).length === 0) {
                appendableItem = createGroupDiv("locationTypeGroup", data.paikkatyyppiryhmaKoodi, locationTypeGroup[language], 2);
                $("#categoryView").append(appendableItem);
            }
            if ($("#locationType_" + data.paikkatyyppiKoodi).length === 0) {
                appendableItem = createGroupDiv("locationType", data.paikkatyyppiKoodi, locationType[language], 3);
                $("#locationTypeGroup_" + data.paikkatyyppiryhmaKoodi).append(appendableItem);
            }
            text = $("#cat_" + feature.fid).html();
            // Jos kohde ei ole listassa, lisää se
            if (text === null) {
                addFeatureIntoGroup("locationType", feature, municipality[language], locationType[language], language);
            }
        }
    }
    
     /**
      * Prints features on map into csv format
      */
    featuresToCSV = function() {
        var csvfeature = wfs.features,
            csvstr = '<div id="csv" style="white-space: nowrap;">';
        csvstr += "fin,fin_kieliEnemmistoKoodi,fin_kieliKoodi,fin_kieliVirallisuusKoodi,swe,swe_kieliEnemmistoKoodi,swe_kieliKoodi,swe_kieliVirallisuusKoodi,eng,eng_kieliEnemmistoKoodi,eng_kieliKoodi,eng_kieliVirallisuusKoodi,sme,sme_kieliEnemmistoKoodi,sme_kieliKoodi,sme_kieliVirallisuusKoodi,smn,smn_kieliEnemmistoKoodi,smn_kieliKoodi,smn_kieliVirallisuusKoodi,sms,sms_kieliEnemmistoKoodi,sms_kieliKoodi,sms_kieliVirallisuusKoodi,kuntaKoodi,laaniKoodi,maakuntaKoodi,mittakaavarelevanssiKoodi,paikannimiID,paikannimiLuontiAika,paikannimiMuutosAika,paikkaID,paikkaLuontiAika,paikkaMuutosAika,paikkatyyppiKoodi,paikkatyyppialaryhmaKoodi,paikkatyyppiryhmaKoodi,pp6Koodi,seutukuntaKoodi,suuralueKoodi,tm35Fin7Koodi,ylj7Koodi";
        csvstr += "<br>";

        for (var i in csvfeature) {
            // Add only selected items to CSV view
            if ($("#visibility_locationTypeGroup_" + csvfeature[i].data.paikkatyyppiryhmaKoodi).is(":checked") &&
                    $("#visibility_locationType_" + csvfeature[i].data.paikkatyyppiKoodi).is(":checked")) {
                if (csvfeature[i].names.fin) {
                    csvstr += csvfeature[i].names.fin.kirjoitusasu + ',';
                    csvstr += csvfeature[i].names.fin.kieliEnemmistoKoodi + ',';
                    csvstr += csvfeature[i].names.fin.kieliKoodi + ',';
                    csvstr += csvfeature[i].names.fin.kieliVirallisuusKoodi + ',';
                } else {
                    csvstr += ',,,,';
                }
                if (csvfeature[i].names.swe) {
                    csvstr += csvfeature[i].names.swe.kirjoitusasu + ',';
                    csvstr += csvfeature[i].names.swe.kieliEnemmistoKoodi + ',';
                    csvstr += csvfeature[i].names.swe.kieliKoodi + ',';
                    csvstr += csvfeature[i].names.swe.kieliVirallisuusKoodi + ',';
                } else {
                    csvstr += ',,,,';
                }
                if (csvfeature[i].names.eng) {
                    csvstr += csvfeature[i].names.eng.kirjoitusasu + ',';
                    csvstr += csvfeature[i].names.eng.kieliEnemmistoKoodi + ',';
                    csvstr += csvfeature[i].names.eng.kieliKoodi + ',';
                    csvstr += csvfeature[i].names.eng.kieliVirallisuusKoodi + ',';
                } else {
                    csvstr += ',,,,';
                }
                if (csvfeature[i].names.sme) {
                    csvstr += csvfeature[i].names.sme.kirjoitusasu + ',';
                    csvstr += csvfeature[i].names.sme.kieliEnemmistoKoodi + ',';
                    csvstr += csvfeature[i].names.sme.kieliKoodi + ',';
                    csvstr += csvfeature[i].names.sme.kieliVirallisuusKoodi + ',';
                } else {
                    csvstr += ',,,,';
                }
                if (csvfeature[i].names.smn) {
                    csvstr += csvfeature[i].names.smn.kirjoitusasu + ',';
                    csvstr += csvfeature[i].names.smn.kieliEnemmistoKoodi + ',';
                    csvstr += csvfeature[i].names.smn.kieliKoodi + ',';
                    csvstr += csvfeature[i].names.smn.kieliVirallisuusKoodi + ',';
                } else {
                    csvstr += ',,,,';
                }
                if (csvfeature[i].names.sms) {
                    csvstr += csvfeature[i].names.sms.kirjoitusasu + ',';
                    csvstr += csvfeature[i].names.sms.kieliEnemmistoKoodi + ',';
                    csvstr += csvfeature[i].names.sms.kieliKoodi + ',';
                    csvstr += csvfeature[i].names.sms.kieliVirallisuusKoodi + ',';
                } else {
                    csvstr += ',,,,';
                }

                csvstr += csvfeature[i].data.kuntaKoodi + ',';
                csvstr += csvfeature[i].data.laaniKoodi + ',';
                csvstr += csvfeature[i].data.maakuntaKoodi + ',';
                csvstr += csvfeature[i].data.mittakaavarelevanssiKoodi + ',';
                csvstr += csvfeature[i].data.paikannimiID + ',';
                csvstr += csvfeature[i].data.paikannimiLuontiAika + ',';
                csvstr += csvfeature[i].data.paikannimiMuutosAika + ',';
                csvstr += csvfeature[i].data.paikkaID + ',';
                csvstr += csvfeature[i].data.paikkaLuontiAika + ',';
                csvstr += csvfeature[i].data.paikkaMuutosAika + ',';
                csvstr += csvfeature[i].data.paikkatyyppiKoodi + ',';
                csvstr += csvfeature[i].data.paikkatyyppialaryhmaKoodi + ',';
                csvstr += csvfeature[i].data.paikkatyyppiryhmaKoodi + ',';
                csvstr += csvfeature[i].data.pp6Koodi + ',';
                csvstr += csvfeature[i].data.seutukuntaKoodi + ',';
                csvstr += csvfeature[i].data.suuralueKoodi + ',';
                csvstr += csvfeature[i].data.tm35Fin7Koodi + ',';
                csvstr += csvfeature[i].data.ylj7Koodi;
                csvstr += "<br>";
            }
        }
        csvstr += "</div>";

        var csvWindow = window.open('', 'csv');
        csvWindow.document.title = "CSV";
        csvWindow.document.write(csvstr);
    }
    
    /**
     * Parses the results of the search.
     *
     * @param {object} features An array of the features that were retrieved in the last search.
     */
    this.parseFeatures = function (features) {
        var i,
            header,
            language = $("#languageSelect").val(),
            searchTerm = $("#searchBox").val().charAt(0).toUpperCase() +
                $("#searchBox").val().slice(1);

        // Checks to see whether earlier results should be kept and updates the 
        // results header accordingly.
        if ($("#keepResults").is(":checked") == true) {
            header = $("#resultsHeader").text();
            header = "<div id='resultsHeader'><h2>" + header + ", \"" + searchTerm + "\", " +
                features.length + " kappaletta</h2></div>";
            $("#resultsHeader").empty().append(header);
        } else {
            $("#categoryView").empty().append("<div id='resultsHeader'><h2>\"" + searchTerm + "\", " +
                    features.length + " kappaletta</h2></div>");
            $("#listView").empty();
        }
        for (i in features) {
            if (features[i] !== "__proto__") {
                addFeatureListing(features[i], language);
            }
        }
        header = $("#resultsHeader").text();
        removeUnCheckedLocations(features);
    };
}